/*
	PacoBlaze test
*/

`define PACOBLAZE3M
`define TEST_FILE "/home/snepomny/paco/pacoblaze-2.2/test/hello.rmh"

`include "timescale_inc.v"
`include "pacoblaze_inc.v"

`define SIM

module pacoblaze3m_tb;

parameter tck = 10, program_cycles = 1024;

//reg clk, 
/*input clk;
input in;
output out;*/

reg clk;
reg rst, ir; // clock, reset, interrupt request
wire [`code_depth-1:0] ad; // instruction address
wire [`operand_width-1:0] pa, po; // port id, port output
wire rd, wr; // read strobe, write strobe
`ifdef HAS_INTERRUPT_ACK
wire ia; // interrupt acknowledge
`endif

reg [`operand_width-1:0] prt[0:`port_size-1]; // port memory

wire [`code_width-1:0] di; // program data input
wire [`operand_width-1:0] pi = prt[pa]; // port input
wire [`scratch_depth-1:0] ram_address;
wire [`scratch_width-1:0] ram_write;
wire [`scratch_width-1:0] ram_read;
wire ram_write_en;
wire ram_en;
 
/* PacoBlaze program memory */
blockram #(.width(`code_width), .depth(`code_depth))
	rom(
	.clk(clk),
	.rst(rst),
	.enb(1'b1),
	.wen(1'b0),
	.addr(ad),
	.din(`code_width 'b0),
	.dout(di)
);


/* PacoBlaze ram */
memory_scratch scratch(
	.address(ram_address),
	.write_enable(ram_write_en), 
	.data_in(ram_write), 
	.data_out(ram_read),
	.reset(1'b0),
	.clk(clk)
);



/* PacoBlaze dut */
pacoblaze3m dut(
	.clk(clk),
	.reset(rst),
	.address(ad),
	.instruction(di),
	.ram_address(ram_address), 
	.ram_write(ram_write), 
	.ram_read(ram_read), 
	.ram_write_en(ram_write_en), 
	.ram_en(ram_en),
	.port_id(pa),
	.read_strobe(rd),
	.write_strobe(wr),
	.in_port(pi),
	.out_port(po),
	.interrupt(ir)
`ifdef HAS_INTERRUPT_ACK
	,	.interrupt_ack(ia)
`endif
);


`ifdef SIM
/* Clocking device */
always #(tck/2) clk = ~clk;

/* Watch port memory */
always @(posedge clk)	if (wr) prt[pa] <= po;

/* Simulation setup */
initial begin
	$dumpvars(0, dut);
	$dumpfile("pacoblaze3m_tb.vcd");
	$readmemh(`TEST_FILE, rom.ram);
`ifdef HAS_DEBUG
	$monitor("%s", dut.idu_debug);
`endif
end

/* Simulation */
integer i;
initial begin
	for (i=0; i<`port_size; i=i+1) prt[i] = i; // initialize ports
	clk = 0; rst = 1; ir = 0;
	#(tck*2);
	@(negedge clk) rst = 0; // free processor

//	#(tck*30);
//	@(negedge clk) ir = 1; // interrupt request
//	// @(negedge clk) ;
//	@(negedge clk) ir = 0;

	#(program_cycles*tck+100) $finish;
end
`endif
endmodule
